﻿#pragma once
#define LK_FUNCTIONAL_ACTION_
namespace LK
{
		/**@brief 表示一个动作(引用）*/
		template<>struct ptr<Functional::IActions > :Functional::PFunObject<weakptr<Functional::IActions >, VarArgsPack<void, void>, true>
		{
			PMETHODS(ptr, Functional::IActions)
			/**
			@brief 使用指定的委托和参数数组来创建*/
			ptr(Functional::PDelegates d, ptr<Collection::IArray<ptr<Object>>> args = null);
			/**
			@brief 使用指定的委托和参数来创建*/
#ifdef SUPPORT_VARIADIC_TEMPLATES
		private:
			template<class T0, class ...Args>ptr AddArgs(T0 t0, Args ... t);
		public:
			template<class T0, class ...Args>ptr(Functional::PDelegates d, T0 t0, Args ... t);
#else
#define TMPCT(x) ,class T##x
#define TMPT(x) ,T##x
#define TMPF(x)\
		template<MF4_RepeatAsc_(class T,,1,x)>ptr(Functional::PDelegates d MF3_RepeatAsc(TMPT,1,x));\
		template<class T0 MF3_RepeatAsc(TMPCT,1,x)> ptr AddArgs(ptr<String> const&functionName MF3_RepeatAsc(TMPT,0,x))const;
			MF2_Repeatb(TMPF, _MRP_CNTM1)
#undef TMPF
#undef TMPCT
#undef TMPT
#endif
		private:
			template<class T0>ptr AddArgs(T0 t0);
		public:
			/**
			@brief 同步执行动作*/
			void Do() const;
			/**
			@brief 同步执行动作，同Do()*/
			void operator()()const;
			/**
			@brief 启动一个新线程来异步执行动作*/
			index_t DoSync()const;
			/**
			@brief 清理所有委托和参数*/
			void Clear()const;
			/**
			@brief 获取返回值的引用*/
			ptr<Object>& GetReturnValRef()const;
			/**
			@brief 获取内部委托的引用*/
			Functional::PDelegates& GetDelegateRef()const;
			/**
			@brief 获取参数列表数组的引用*/
			ptr<LK::Collection::IArray<ptr<Object>>>& GetArgumentsRef()const;
			/**
			@brief 获取动作执行结束后继续执行的下一个动作的引用*/
			ptr<Functional::IActions > GetNextActionRef()const;
			/**
			@brief 获取动作当前状态的引用（不一定是准确的，因为获取状态的瞬间可能发生改变）*/
			index_t& GetStateRef()const;
			/**
			@brief 获取动作已执行的次数的引用（不一定是准确的，，因为获取状态的瞬间可能发生改变）*/
			index_t& GetDidCountRef()const;
		};
	namespace Functional
	{
		/**@brief 表示一个动作接口*/
		struct IActions :FunObject<weakptr<IActions>, VarArgsPack<void, void>, true>
		{
			BMETHODS(ptr<IActions>, IActions)
			/**
			@brief 返回一个浅表副本*/
			IActions* Clone()const { return new IActions(*this); }
			/**
			@brief 内部委托*/
			PDelegates delegates;
			/**
			@brief 委托调用所需参数*/
			ptr<LK::Collection::IArray<ptr<Object>>> args;
			/**
			@brief 返回值（如果有）*/
			ptr<Object> returnVal;
			/**
			@brief 下一个动作*/
			ptr<IActions> nextAction;
			/**
			@brief Action执行次数统计*/
			index_t didCnt;
			/**
			@brief 当前Action的状态（0执行完成，1执行中）*/
			index_t state;
			/**
			@brief 默认构造函数*/
			IActions();
			/**
			@brief 复制构造函数*/
			IActions(IActions const&);
			/**
			@brief 同步执行动作*/
			void Do();
			/**
			@brief 清理*/
			void Clear();
			/**
			@brief 启动一个新线程来异步执行动作，返回线程id*/
			index_t DoSync();
		private:
			static void ThreadFunction(void*);
		};

	}
}
